package Line;

use strict;
use warnings;


sub new {
   my $package = shift;

   my ($x1, $y1, $x2, $y2) = @_;

   my $self = {
      'x1' => $x1,
      'y1' => $y1,
      'x2' => $x2,
      'y2' => $y2,
   );

   return bless $self, $package;
}


=head

Finds the intersection of two lines by finding l1 and l2 in the following
set of equations:

   (1-l1) x11 + l1 x12 = (1-l2) x21 + l2 x22
   (1-l1) y11 + l1 y12 = (1-l2) y21 + l2 y22

This reduces to

   [ x12 - x11    x21 - x22 ] [ l1 ] = [ x21 - x11 ]
   [ y12 - y11    y21 - y22 ] [ l2 ] = [ y21 - y11 ]


=head1 RETURN VALUES

The return values are lambda1 and lambda2. For a true intersection,
both lambba1 and lambda2 must lie between 0 and 1 inclusive. The results
are however applicable in a more general way, when two lines must be 

=cut
# static function intersection
sub intersection {
   my ($line1, $line2) = @_;
   
   my $x11 = $line1 -> {'x1'};
   my $x12 = $line1 -> {'x2'};
   my $y11 = $line1 -> {'y1'};
   my $y12 = $line1 -> {'y2'};

   my $x21 = $line2 -> {'x1'};
   my $x22 = $line2 -> {'x2'};
   my $y21 = $line2 -> {'y1'};
   my $y22 = $line2 -> {'y2'}; 

   # find the matrix coefficients
   my $a11 = $x12 - $x11; my $a12 = $x21 - $x22;
   my $a21 = $y12 - $y11; my $a22 = $y21 - $y22;

   # find the determinant
   my $det = $a12 * $a22 - $a12 * $a21;

   # if the determinant is very small, the lines are (nearly) parallel

   if (abs ($det) <= 1.0e-3) {
      return (undef, undef);
   }
   else {
      # determine the right-hand-side of the equation
      my $r1 = $x21 - $x11;
      my $r2 = $y21 - $y11;

      my $l1 = (   $a22 * $r1 - $a12 * $r2 ) / $det;
      my $l2 = (  -$a21 * $r1 - $a11 * $r2 ) / $det;

      return ($l1, $l2);
   }
}

# module OK
1;

